#include "app_includes.h"

app_device_t app_dev;
device_factor_t app_dev_factor;

static void app_dev_para_check(void);

void app_dev_info_init(void)
{
    memset(&app_dev.para.info, 0 , sizeof(app_dev.para.info));
    strcpy(app_dev.para.info.name, "FL POWER V3");
    strcpy(app_dev.para.info.os, "FreeRTOS10.2.0.1");
    strcpy(app_dev.para.info.buildVersion, BUILD_VERSION);
    board_get_uid_6(app_dev.mc_id);
}

void app_dev_init(void)
{
    uint8_t i;
    uint16_t map_offset = 0;
    uint16_t pid_offset = 0;
    
    app_dev_info_init();
    device_wave_init(0,100);
    
    app_dev.para_package = &para_package;
    app_dev.src_package = &src_package;
    
    memset(&app_dev.meter.group[0], 0, sizeof(&app_dev.meter));
    
    
    board_memory_read(DEVICE_STORE_ADDR, (uint8_t *)&app_dev.para.store, sizeof(app_dev.para.store));
    board_memory_read(DEVICE_FACTOR_ADDR, (uint8_t *)&app_dev_factor, sizeof(app_dev_factor));
    
    app_dev_para_check();
    
    for(i=0;i!=SRC_TABLE_METER_ITEM_NUM;i++) {
        app_dev.meter.group[i].id = i;
        app_dev.meter.group[i].map = &app_dev_factor.map[map_offset];
        app_dev.meter.group[i].pid = &app_dev_factor.pid[pid_offset];
        app_dev.meter.group[i].map_offset = map_offset;
        app_dev.meter.group[i].pid_offset = pid_offset;
        map_offset += app_dev.src_package->item[i].attr.meter.map_num;
        pid_offset += app_dev.src_package->item[i].attr.meter.ctrl_num;
    }
    //绑定索引
    
    app_dev.para.run.power_set_u = 5000;
    app_dev.para.run.power_set_i = 1000;
    
    //测试用
    
    //app_dev.para.store.pc_comm = 1;
}

void app_dev_meter_update(uint8_t id, float value) 
{
    app_dev.meter.group[id].value_ins = value;
    app_dev.meter.group[id].value_total -= app_dev.meter.group[id].value_buff[app_dev.meter.group[id].cnt];
    app_dev.meter.group[id].value_buff[app_dev.meter.group[id].cnt] = app_dev.meter.group[id].value_ins;
    app_dev.meter.group[id].value_total += app_dev.meter.group[id].value_buff[app_dev.meter.group[id].cnt];
    if(++app_dev.meter.group[id].cnt==DEVICE_METER_BUFF_SIZE)
        app_dev.meter.group[id].cnt = 0;
    app_dev.meter.group[id].value = app_dev.meter.group[id].value_total / DEVICE_METER_BUFF_SIZE;
}

void app_dev_meter_cal(uint8_t id, int32_t adc_value)
{
    uint8_t i;
    float result = 0;
    uint8_t num = app_dev.src_package->item[id].attr.meter.map_num;
    map_para_t *factor = app_dev.meter.group[id].map;
    app_dev.meter.group[id].adc = adc_value;
    if(adc_value<=factor[0].adc)
        i = 0;
    else if(adc_value>=factor[num-1].adc)
        i = num-2;
    else {
        for(i=0;i!=num-1;i++) {
            if(adc_value>factor[i].adc && adc_value<factor[i+1].adc)
                break;
        }
    }
    result = factor[i].value + (adc_value-factor[i].adc)*(factor[i+1].value-factor[i].value)/(factor[i+1].adc-factor[i].adc);

    app_dev_meter_update(id, result);
    /*    
    app_dev.meter.group[id].value_total -= app_dev.meter.group[id].value_buff[app_dev.meter.group[id].cnt];
    app_dev.meter.group[id].value_buff[app_dev.meter.group[id].cnt] = app_dev.meter.group[id].value_ins;
    app_dev.meter.group[id].value_total += app_dev.meter.group[id].value_buff[app_dev.meter.group[id].cnt];
    if(++app_dev.meter.group[id].cnt==DEVICE_METER_BUFF_SIZE)
        app_dev.meter.group[id].cnt = 0;
    app_dev.meter.group[id].value = app_dev.meter.group[id].value_total / DEVICE_METER_BUFF_SIZE;
    */
}

void app_dev_para_check(void)
{
    if(app_dev.para.store.display_dir>3)
        app_dev.para.store.display_dir = 3;
    if(app_dev.para.store.lcd_light<10)
        app_dev.para.store.lcd_light = 10;
}

void app_dev_para_init(void)
{
    //更新显示方向
    uint16_t angle[] = {0, 90, 180, 270};
    lcd_154hsc04a_rotation(&board.lcd_dev, angle[app_dev.para.store.display_dir]);
    //更新背光
    led_on_adjust(&board.lcd_backlight, app_dev.para.store.lcd_light*2);
    lcd_sleep_time = app_dev.para.store.lcd_sleep_time*60*1000;
    //更新蜂鸣器提示音量
    buzzer_set_volume(&board.buzzer, kBuzzerVolume_Max/20*app_dev.para.store.buzzer_vol, 50);
}

device_para_status_t status_new;

void device_status_refresh(void)
{
    uint8_t i;
    status_new.power_work = app_dev.para.run.power_enable;
    
    uint8_t *p1 = (uint8_t *)&status_new;
    uint8_t *p2 = (uint8_t *)&app_dev.para.status;
    for(i=0;i!=sizeof(device_para_status_t);i++) { //比较数据是否有变化
        if(*(p1+i) != *(p2+i)) {
            memcpy(p2,p1,sizeof(device_para_status_t));
            xEventGroupSetBits(sys_event, kSysEvent_ParaChange|kSysEvent_UIParaChange);
            break;
        }
    }
}

float app_dev_meter_get_max(uint8_t id) 
{
    uint8_t i;
    float max = app_dev.meter.group[id].value_buff[0];
    for(i=1;i!=DEVICE_METER_BUFF_SIZE;i++) {
        if(max<app_dev.meter.group[id].value_buff[i])
            max = app_dev.meter.group[id].value_buff[i];
    }
    return max;
}

/* 波形校准数据 */
void device_wave_init(uint8_t id, uint16_t interval)
{
    app_dev.wave.pid = NULL;
    if(id==0) {
        board_cnt_stop(&app_dev.wave.cnt);
    }
    else {
        board_cnt_sync(&app_dev.wave.cnt);
    }
    app_dev.wave.id = id;
    app_dev.wave.interval = interval;
    app_dev.wave.end = 0;
    app_dev.wave.head = 0;
    app_dev.wave.len = 0;
}

uint8_t device_wave_read(uint8_t *p, uint8_t len)
{
    uint8_t i;
    uint8_t size = sizeof(device_wave_data_t);
    if(len>app_dev.wave.len)
        return 1;
    for(i=0;i!=len;i++)
    {
        memcpy(p+i*size, &app_dev.wave.data[app_dev.wave.head++], size);
        app_dev.wave.len--;
    }
    return 0;
}

void device_wave_cnt(void)
{
    if(app_dev.wave.id>0 && app_dev.wave.id<=SRC_TABLE_METER_ITEM_NUM && 
       board_cnt_get_interval(&app_dev.wave.cnt)>=app_dev.wave.interval)
    {
        board_cnt_sync(&app_dev.wave.cnt);
        if(app_dev.wave.len==DEVICE_WAVE_DATA_NUM) //缓存满了，head丢弃一位
            app_dev.wave.head++;
        else
            app_dev.wave.len++;
        app_dev.wave.data[app_dev.wave.end].value = app_dev.meter.group[app_dev.wave.id-1].value_ins;
        if(app_dev.wave.pid!=NULL) {
            app_dev.wave.data[app_dev.wave.end].ep = app_dev.wave.pid->ep;
            app_dev.wave.data[app_dev.wave.end].ei = app_dev.wave.pid->ei;
            app_dev.wave.data[app_dev.wave.end].ed = app_dev.wave.pid->ed;
        }
        app_dev.wave.end++;
    }
}

void device_pwm_out(uint8_t id, uint16_t value)
{
    if(app_dev.out.group[id].lock==0) {
        app_dev.out.group[id].value = value;
        board_pwm_out(id, value);
    }
}

void device_pwm_out_test(uint8_t id, uint16_t value, uint8_t lock)
{
    app_dev.out.group[id].lock = lock;
    app_dev.out.group[id].value = value;
    board_pwm_out(id, value);
}
